// Copyright (C) 2010 and onwards Noam Shazeer and Georges Harik
// Pieces of this code may be licenced under the Apache License, version 2.0 
//   from Harik Shazeer Labs
#ifndef _FILE_H_
#define _FILE_H_

// Files are either normal files or sharded files
// Normal files have normal paths
// Sharded files have a 2 part path separated by a !
// e.g. /store!hi
// for now, no subdirectories after the ! sign
//
// We support the following operations on files
// Filesize, MMap, Read, Read (placement), Write
//
// A shard directory has a particular directory structure
// a file: "meta" with metainformation for it
// directories 0 .. (#shards - 1)

#include "util.h"
#include "jobqueue.h"

namespace File {
  bool Exists(string fn);
  uint64 Size(string fn);
  void Write(string fn, Memblock data);

  // Placement read. Caller's job to zero-out byte at end of memblock
  void Read(string fn, Memblock data);

  // Allocate and read. Zeroes out byte at end of memblock.
  Memblock Read(string fn);

  // Zeroes out byte at end of memblock
  // Memblock Mmap(string fn); // Not really working

  // Helper functions
  bool IsSharded(string name);
  string Part0(string name);
  string Part1(string name);
  uint64 NumShards(string p0);
  string ShardFile(string fn, uint64 shard);
  uint64 ShardBytes(uint64 total_bytes, 
		    uint64 shard, 
		    uint64 num_shards);
};


struct WriteTask : public JobQueue::Task {
  WriteTask(string fn, Memblock block) {
    fn_ = fn;
    block_ = block; }
  void Run() { block_.WriteToFile(fn_); }
  string fn_;
  Memblock block_;
};

struct ReadTask : public JobQueue::Task {
  ReadTask(string fn, Memblock block) {
    fn_ = fn;
    block_ = block; }
  void Run() { block_.ReadFromFile(fn_); }
  string fn_;
  Memblock block_; 
};

int file_main();

/*
namespace Store {
  void Store(string fn, Memblock data);
  Memblock Load(string fn);
  void Load(string fn, Memblock data);
  uint64 FileSize(string fn);
  
  string ShardFileName(string fn, uint64 shard);
  string InfoFileName(string fn);
  uint64 ShardBytes(uint64 total_bytes, uint64 shard);
};
*/

#endif
